﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace HREntities
{
    public delegate void PayDelegate (IPayable ip, decimal amt);
    public delegate void EntityChanged(TaxEntity e, string hint);

    public abstract class TaxEntity :  IPayable
    {
        public event EntityChanged changeEvents;

        private void TriggerEvent(string hint)
        {
            if (changeEvents != null)
                changeEvents(this, hint);
        }

        #region fields
        private string name;
        private TaxID taxid;
        #endregion

        public TaxEntity(string name, TaxID taxid)
        {
            Name = name;
            TaxID = taxid;
        }

        #region properties
        public TaxID TaxID
        {
            get { return taxid; }
            set { taxid = value; TriggerEvent("taxid"); }
        }

        /// <summary>
        /// This is the name of the company. Must be 2-50 chars long.
        /// </summary>
        /// <example>
        ///     Company c = new Company(...);
        ///     c.Name = "Acme";
        /// </example>
        /// <exception cref="ArgumentException">
        ///     if the name isn't correct
        /// </exception>
        /// 
        public string Name
        {
            get { return name; }
            set
            {
                if (value != null &&
                    Regex.IsMatch(value, @"^[\w\-\.\,\s]{2,50}$"))
                {
                    name = value; // assign value to name
                    TriggerEvent("name");
                }
                else
                    throw new ArgumentException("name cannot be null");
            }
        }
        #endregion

        /// <summary>
        /// Pays every object in this entity.
        /// </summary>
        /// <returns></returns>
        public abstract decimal Pay();


        int IComparable<IPayable>.CompareTo(IPayable other)
        {
            return Name.CompareTo(other.Name);

        }
    }
}
